package com.micro.plugins.jwt.runner;

import com.micro.common.MicroConstant;
import com.micro.plugins.jwt.helper.RsaKeyHelper;
import com.micro.plugins.jwt.load.JwtLoadConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

/**
 * <h2>jwt授权定时</h2>
 * @author LevelCoder
 * @version V1.0.0
 * @email LevelCoder@126.com
 * @date 2020/5/12
 */
@Slf4j
@Configuration
public class JwtAuthRunner implements CommandLineRunner {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private final JwtLoadConfiguration jwtLoadConfiguration;

    @Autowired
    public JwtAuthRunner(JwtLoadConfiguration jwtLoadConfiguration) {
        this.jwtLoadConfiguration = jwtLoadConfiguration;
    }


    @Override
    public void run(String... args) throws Exception {
        try {
            loadingUserPubKey();
            log.info("初始化加载用户pubKey");
        } catch (Exception e){
            log.error("初始化加载用户pubKey失败,5秒后自动重试!",e);
//            refreshUserPubKey();
        }
    }


//    @Scheduled(cron = "0 10 * * * ?")
//    public void refreshUserPubKey() {
//        try {
//            InitializeLoadUserPubKey();
//            log.info("重新加载用户pubKey成功,之前下发的凭证全部作废！");
//        } catch (NoSuchAlgorithmException e) {
//            log.error("用户公匙生成错误，请检查系统！");
//        }
//    }

    /**
     * 加载 jwt
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    private void loadingUserPubKey() throws IOException, NoSuchAlgorithmException {
        if (redisTemplate.hasKey(MicroConstant.RedisKeyPrefix.REDIS_USER_PRI_KEY)&&redisTemplate.hasKey(MicroConstant.RedisKeyPrefix.REDIS_USER_PUB_KEY)) {
            jwtLoadConfiguration.setUserPriKey(RsaKeyHelper.toBytes(redisTemplate.opsForValue().get(MicroConstant.RedisKeyPrefix.REDIS_USER_PRI_KEY).toString()));
            jwtLoadConfiguration.setUserPubKey(RsaKeyHelper.toBytes(redisTemplate.opsForValue().get(MicroConstant.RedisKeyPrefix.REDIS_USER_PUB_KEY).toString()));
        }else {
            InitializeLoadUserPubKey();
        }
    }

    /**
     * 初始化加载 jwt
     * @throws NoSuchAlgorithmException
     */
    private void InitializeLoadUserPubKey() throws NoSuchAlgorithmException {
        log.info("缓存中存储的原UserPubKey:{}",redisTemplate.opsForValue().get(MicroConstant.RedisKeyPrefix.REDIS_USER_PRI_KEY));
        log.info("缓存中存储的原UserPriKey:{}",redisTemplate.opsForValue().get(MicroConstant.RedisKeyPrefix.REDIS_USER_PUB_KEY));
        Map<String, byte[]> keyMap = RsaKeyHelper.generateKey(jwtLoadConfiguration.getMicroJwt().getUserRasSecret());
        jwtLoadConfiguration.setUserPriKey(keyMap.get("pri"));
        jwtLoadConfiguration.setUserPubKey(keyMap.get("pub"));
        redisTemplate.opsForValue().set(MicroConstant.RedisKeyPrefix.REDIS_USER_PRI_KEY, RsaKeyHelper.toHexString(keyMap.get("pri")));
        redisTemplate.opsForValue().set(MicroConstant.RedisKeyPrefix.REDIS_USER_PUB_KEY, RsaKeyHelper.toHexString(keyMap.get("pub")));
        log.info("缓存中存储的修改UserPubKey:{}",redisTemplate.opsForValue().get(MicroConstant.RedisKeyPrefix.REDIS_USER_PRI_KEY));
        log.info("缓存中存储的修改UserPriKey:{}",redisTemplate.opsForValue().get(MicroConstant.RedisKeyPrefix.REDIS_USER_PUB_KEY));
        log.info("UserPubKey:{}",this.jwtLoadConfiguration.getUserPubKey());
        log.info("UserPriKey:{}",this.jwtLoadConfiguration.getUserPriKey());
    }

}
